package com.lanier.dydownloader

import android.annotation.SuppressLint
import android.app.AlertDialog
import android.content.DialogInterface
import android.content.Intent
import android.graphics.Bitmap
import android.net.Uri
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.text.TextUtils
import android.util.Log
import android.view.WindowManager
import android.webkit.CookieManager
import android.webkit.JavascriptInterface
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.isVisible
import androidx.lifecycle.lifecycleScope
import com.lanier.dydownloader.databinding.AtyWebBinding
import io.wongd.lib_douyin.download.DownloadTask
import io.wongd.lib_douyin.download.JoinDownloadTaskFlow
import com.lanier.dydownloader.utils.ClipboardUtil
import com.lanier.dydownloader.utils.Mht2HtmlUtil
import com.lanier.dydownloader.utils.WebUtil
import com.lanier.lib_js_bridge.BridgeWebViewClient
import com.tencent.smtt.export.external.interfaces.WebResourceRequest
import com.tencent.smtt.export.external.interfaces.WebResourceResponse
import com.tencent.smtt.sdk.WebChromeClient
import com.tencent.smtt.sdk.WebSettings
import com.tencent.smtt.sdk.WebView
import io.wongd.lib_douyin.Douyin
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import org.jsoup.Jsoup
import org.jsoup.nodes.Document
import us.codecraft.xsoup.Xsoup
import java.io.File
import java.io.FileOutputStream
import java.io.OutputStreamWriter
import java.util.concurrent.atomic.AtomicBoolean
import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine


class AtyWeb : AppCompatActivity() {


    private lateinit var b: AtyWebBinding

    private lateinit var url: String
    private var webTitle = ""
    private val hasShowDownloadDialog = AtomicBoolean(false)

    private val handler: Handler = Handler(Looper.getMainLooper())

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        b = AtyWebBinding.inflate(layoutInflater)
        setContentView(b.root)

        window.setSoftInputMode(
            WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN or
                    WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN
        )
        handler.postDelayed({
            try {
                //解决h5输入法遮挡问题
                window.setSoftInputMode(
                    WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE or
                            WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE
                )
            } catch (ignored: Exception) {
            }
        }, 1000)

        url = intent.getStringExtra("url") ?: ""
        if (TextUtils.isEmpty(url)) {
            finish()
            return
        }
        initData(url)

        b.getHtml.setOnClickListener {
            afterPageFinish()
        }
    }

    override fun onResume() {
        super.onResume()
        b.webView.onResume()
    }

    override fun onPause() {
        super.onPause()
        b.webView.onPause()
    }

    override fun onDestroy() {
        super.onDestroy()
        b.webView.removeAllViews()
        b.webView.destroy()
        //异常所以的信息
        handler.removeCallbacksAndMessages(null)
    }

    private fun writeToFile(text: String, fileName: String) {
        val file = File(cacheDir, fileName)
        if (file.exists()) file.delete()
        file.createNewFile()
        val outputStream = FileOutputStream(file)
        val outputStreamWriter = OutputStreamWriter(outputStream)
        outputStreamWriter.write(text)
        outputStreamWriter.close()
    }

    private val urlList = mutableListOf<String>()
    private suspend fun getPostUrls(): List<String> {

//        return suspendCoroutine<List<String>> { co ->
        // view.loadUrl("javascript:window.local_obj.showSource('<head>'+document.getElementsByTagName('html')[0].innerHTML+'</head>');")
        // https://blog.csdn.net/spinchao/article/details/104769061
//            b.webView.evaluateJavascript("document.getElementById('root').innerHTML;") { data ->
////            b.webView.evaluateJavascript("document.getElementsByTagName('body')[0].innerHTML;") { data ->
//
//                println("网页: html内容 onReceiveValue dataSize:${data.length}")
//                writeToFile(data, "douyinHtml.txt")
//
//                val document: Document = Jsoup.parse(data)
//
////                    println("网页: html内容 document :${document}")
//                var list = Xsoup.compile("//a[contains(@href,'/video/')]").evaluate(document).list()
//                println("网页: html内容 list size:${list.size}")
//
//
////                list.forEach {
////                    val result = Xsoup.compile("//a/@href").evaluate(Jsoup.parse(it)).get()
////                    if (result.contains("https://").not()) println("网页: html内容 单个Url:https://www.douyin.com$result")
////                }
//
//                // 字符串匹配
//                if (list.isEmpty()) {
//                    list = T.findAllInText(T.bodyHtml)
//                }
//
//                println("信息: list size:${list.size}")
//
//                co.resume(list.map { "https://www.douyin.com$it" })
//            }
//
//        }


        return suspendCoroutine { co ->

            val dir = File(application.cacheDir, tempHtmlFileName)
            if (dir.exists().not()) dir.mkdir()

            b.webView.saveWebArchive(dir.path, true) { data ->
                if (data == null) {
                    co.resume(emptyList())
                    return@saveWebArchive
                }

                Mht2HtmlUtil.mht2html(data, "${data}/tmp.html")

                println("网页: html内容 saveWebArchive dataSize:${data.length},  data:$data")
                val document: Document = Jsoup.parse(data)
                val list = Xsoup.compile("//a[contains(@href,'/video/')]").evaluate(document).list()
                println("网页: html内容 list size:${list.size}")
                list.forEach {
                    val result = Xsoup.compile("//a/@href").evaluate(Jsoup.parse(it)).get()
                    if (result.contains("https://").not()) println("网页: html内容 单个Url:https://www.douyin.com$result")
                }

                co.resume(list.map { "https://www.douyin.com$it" })
            }

        }

    }

    private val tempHtmlFileName = "douyinTmp"

    private fun afterPageFinish() {

        lifecycleScope.launch {
            val list = mutableListOf<String>()
            var count = 0
//            do {
            delay(1500)
            list.addAll(getPostUrls())
            count++
//            } while (list.isEmpty() && count < 6)

            list.filter { urlList.contains(it).not() }.forEach {
                println("网页: html内容 单个Url:$it")
                urlList.add(it)
            }

            println("网页: html内容 当前总共urlSize:${urlList.size}")
        }
    }

    private fun judgeCookie(url: String?): Pair<Boolean, String> {
        if (url.isNullOrBlank()) return false to ""

        val cookieManager = CookieManager.getInstance()
        val cookieStr = cookieManager.getCookie(url)

        Log.d("网页", "judgeCookie 地址：$url，  cookieStr:$cookieStr")

        return (url.split(";").size > 5) to cookieStr
    }

    inner class InJavaScriptLocalObj {
        @JavascriptInterface
        fun showSource(html: String) {
            Log.d("html源码打印", html)
//            writeToFile(html, "sourceHtml.txt")
//            afterPageFinish()
        }
    }


    /**  初始化数据  **/
    @SuppressLint("SetJavaScriptEnabled", "AddJavascriptInterface") // 注解一定要添加
    private fun initData(url: String) {
        Log.d("抖音", url)
//        b.webView.clearCache(true)
        b.webView.addJavascriptInterface(InJavaScriptLocalObj(), "local_obj")
        val webSettings = b.webView.settings
        webSettings.domStorageEnabled = true
        webSettings.javaScriptEnabled = true
        webSettings.builtInZoomControls = true
        webSettings.useWideViewPort = true
        webSettings.loadWithOverviewMode = true
        webSettings.setSupportZoom(true)
        webSettings.cacheMode = WebSettings.LOAD_DEFAULT
        webSettings.setAppCacheEnabled(true)
        webSettings.savePassword = false //屏蔽提示密码保存框
        // 把内部私有缓存目录'/data/data/包名/cache/'作为WebView的AppCache的存储路径
        val cachePath = applicationContext.cacheDir.path
        webSettings.setAppCachePath(cachePath)
        webSettings.setAppCacheMaxSize((50 * 1024 * 1024).toLong())
        webSettings.displayZoomControls = true

        // 设置webview加载的页面的模式,缩放至屏幕的大小
        webSettings.setLoadWithOverviewMode(true)

        b.webView.isHorizontalScrollBarEnabled = true //滚动条水平是否显示
        b.webView.isVerticalScrollBarEnabled = true //滚动条垂直是否显示

        webSettings.userAgentString = Douyin.userAgent

        b.webView.loadUrl(url)
        b.webView.webChromeClient = object : WebChromeClient() {
            override fun onReceivedTitle(p0: WebView?, p1: String) {
                super.onReceivedTitle(p0, p1)
                webTitle = p1
            }
        }
        //1.注意需要设置BridgeWebViewClient不然js交互无效，
        //2.自定义WebViewClient 通过webView打开链接，不调用系统浏览器
        b.webView.webViewClient = object : BridgeWebViewClient(b.webView) {
            override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
                super.onPageStarted(view, url, favicon)
                b.frameLayout.isVisible = true


                Log.d("网页", "onPageStarted 地址：$url，  cookie:${judgeCookie(url).first}")
            }

            override fun onCustomPageFinished(view: WebView, url: String) {
//                view.loadUrl("javascript:window.local_obj.showSource('<head>'+" +
//                        "document.getElementsByTagName('html')[0].innerHTML+'</head>');")

                super.onCustomPageFinished(view, url)
                b.frameLayout.isVisible = false

                // 设置缩放到最小
                view.setInitialScale(25)

                val judgeCookie = judgeCookie(url)
                Log.d("网页", "onCustomPageFinished 地址：$url，  cookie:${judgeCookie.first}")

                if (judgeCookie.first) Douyin.cookie = judgeCookie.second

//                afterPageFinish()

                // document.getElementById('root').innerHTML

            }

            override fun shouldInterceptRequest(
                webView: WebView,
                webResourceRequest: WebResourceRequest
            ): WebResourceResponse? {
                val requestUrl = webResourceRequest.url.toString()
                Log.d("网页", "shouldInterceptRequest 地址：$requestUrl")
                val hasShow = hasShowDownloadDialog.get()
                if (hasShow) {
                    return super.shouldInterceptRequest(webView, webResourceRequest)
                }
                if (requestUrl.contains("video/") && requestUrl.contains("mp4")) {
                    val type: String = WebUtil.getContentType(requestUrl)
                    if (type.startsWith("video")) {
                        handler.post {
                            val codeArr = type.split("-")
                            val code = if (codeArr.size > 1) {
                                codeArr[1]
                            } else {
                                ""
                            }
                            hasShowDownloadDialog.set(true)
                            showDownloadDialog(
                                title = "完成",
                                onJoinQueue = {
                                    ClipboardUtil.clip(requestUrl)
                                    if (code == "403") {
                                        showAlertDialog(
                                            title = "Dear Smurf:",
                                            message = "视频需要重定向, 文件下载可能异常, 但链接已复制, 可以手动前往浏览器下载.\n\n点击确定继续尝试重定向下载, 点击取消什么都不做",
                                            cancelable = false,
                                            showNegativeButton = true,
                                            onPositive = {
                                                buildTask(requestUrl)
                                                finish()
                                            },
                                            onNegative = {
                                                finish()
                                            }
                                        )
                                    } else {
                                        buildTask(requestUrl)
                                        finish()
                                    }
                                },
                                onOnlyCopyLink = {
                                    ClipboardUtil.clip(requestUrl)
                                    Toast.makeText(this@AtyWeb, "已复制", Toast.LENGTH_SHORT)
                                        .show()
                                    finish()
                                },
                                onToBrowser = {
                                    val intent = Intent(Intent.ACTION_VIEW)
                                    val uri = Uri.parse(requestUrl)
                                    intent.data = uri
                                    startActivity(intent)
                                    finish()
                                },
                                onDoNothing = {
                                    finish()
                                }
                            )
                        }
                    }
                }
                return super.shouldInterceptRequest(webView, webResourceRequest)
            }
        }
    }

    private fun buildTask(requestUrl: String) {
        val task = DownloadTask(
            filename = webTitle.ifEmpty { "无标题" },
            fileLinkUrl = requestUrl,
        )
        Toast.makeText(
            this@AtyWeb,
            "已加入下载队列",
            Toast.LENGTH_SHORT
        )
            .show()
        JoinDownloadTaskFlow.tryEmit(task)
    }

    private fun showDownloadDialog(
        title: String,
        onJoinQueue: () -> Unit,
        onOnlyCopyLink: () -> Unit,
        onToBrowser: () -> Unit,
        onDoNothing: () -> Unit = {},
    ) {
        val items = arrayOf("加入下载队列", "仅复制链接", "跳转到系统浏览器下载", "什么都不做")
        val itemClickListener = DialogInterface.OnClickListener { dialog, which ->
            when (which) {
                0 -> onJoinQueue.invoke()
                1 -> onOnlyCopyLink.invoke()
                2 -> onToBrowser.invoke()
                3 -> onDoNothing.invoke()
            }
            dialog.dismiss()
        }
        AlertDialog.Builder(this)
            .setItems(items, itemClickListener)
            .setTitle(title)
            .setCancelable(false)
            .show()
    }

    private fun showAlertDialog(
        title: String = "Smurf",
        message: String,
        cancelable: Boolean = true,
        showNegativeButton: Boolean = false,
        positiveButtonText: String = "确定",
        negativeButtonText: String = "取消",
        onPositive: () -> Unit,
        onNegative: () -> Unit = {},
    ) {
        val builder = AlertDialog.Builder(this)
        builder.setTitle(title)
        builder.setMessage(message)
        builder.setCancelable(cancelable)
        builder.setPositiveButton(
            positiveButtonText
        ) { dialog, _ ->
            onPositive.invoke()
            dialog.dismiss()
        }
        if (showNegativeButton) {
            builder.setNegativeButton(
                negativeButtonText
            ) { dialog, _ ->
                onNegative.invoke()
                dialog.dismiss()
            }
        }
        builder.show()
    }
}